package peer;

import handover.HandoverManager;
import peer.enums.Network;
import WiFi.WiFiConnectedThread;
import WiFi.WiFiServerThread;
import bluetooth.BluetoothConnectedThread;
import bluetooth.BluetoothServerThread;
import client.ClientConnectable;
import client.PresentationApp;
import exception.NFCException;

public class PeerManager implements ClientConnectable {

	private BluetoothServerThread bluServer;
	private WiFiServerThread wifiServer;
	public WiFiConnectedThread wiFiConnectedThread;
	public BluetoothConnectedThread bluetoothConnectedThread;
	private HandoverManager handoverManager;
	private PeerMessageCenter peerMessageCenter;
	
	//FIXME Tirar isso
	private ClientConnectable frame;

	private static PeerManager instance = null;

	public static PeerManager getInstance() {
		if (instance == null) {
			instance = new PeerManager();
		}
		return instance;
	}

	private PeerManager() {
		frame = new PresentationApp(); //FIXME tirar isso daqui!!
		handoverManager = new HandoverManager();
		peerMessageCenter = new PeerMessageCenter(handoverManager);
	}

	public void start() {
		this.bluServer = new BluetoothServerThread(this);
		this.bluServer.start();

		this.wifiServer = new WiFiServerThread(this);
		this.wifiServer.start();
	}

	

	@Override
	public void receiveData(byte[] array) {
		peerMessageCenter.processData(array);
	}
	
	
	@Override
	public void writeData(byte[] array) throws NFCException {
		write(peerMessageCenter.formatDataMessage(array), true);
	}
	
	public void writeProtocol(byte[] array) throws NFCException {
		write(array, false);
	}
	
	private void write(byte[] array,  boolean isData) throws NFCException {
		Network selection = handoverManager.selectNetwork(!isData);
		if(isData) sendDataToClient(selection == Network.Bluetooth? "##BLUE".getBytes(): "###WIFI".getBytes());//FIXME TIrar
		switch (selection) {
			case None:
				if(isData){
					throw new NFCException("Infrastructure not connected !");
				}
			case Bluetooth:				
				if (bluetoothConnectedThread != null) {
					try {
						bluetoothConnectedThread.write(array);
						handoverManager.notifySuccess(Network.Bluetooth);
					} catch (NFCException e) {
						handoverManager.notifyError(Network.Bluetooth);
					}
				}else
					throw new NFCException("Bluetooth not connected !");
				break;
			case WiFi:
				WiFiConnectedThread copy;
				synchronized (this) {
					copy = wiFiConnectedThread;
					writeDataWiFi(copy, array);
				}
				break;
		}
	}

	private void writeDataWiFi(WiFiConnectedThread thread, byte[] array) {
		if (thread != null) {
			try{
				thread.write(array);
				handoverManager.notifySuccess(Network.WiFi);
			} catch (NFCException e) {
				handoverManager.notifyError(Network.WiFi);
			}
		}
	}
	
		
	//FIXME tirar isso daqui!!
	public void sendDataToClient(byte[] array) {
		frame.receiveData(array);
	}
	

	@Override
	public void setConnectedThread(WiFiConnectedThread conTh) {
		if(wiFiConnectedThread != null){
			wiFiConnectedThread.cancel();
			wiFiConnectedThread.interrupt();
			wiFiConnectedThread = null;
		}
		this.wiFiConnectedThread = conTh;
	}

	@Override
	public void setBluetoothConnectedThread(BluetoothConnectedThread bluConTh) {
		this.bluetoothConnectedThread = bluConTh;
	}
	
	
}
